import { onBeforeMount, provide, ref } from "vue";
import { useWindowSize } from "@vueuse/core";
import { useRoute, useRouter } from "vue-router";
import {
  FieldItem,
  getFormLogicRequest,
  listFixedFormFieldsRequest,
  listFormFieldsRequest,
  MyFormRole
} from "@/api/project/form";
import { getDimensionByKey } from "@/api/project/dimension";
import { useFormInfo } from "@/stores/formInfo";
import { storeToRefs } from "pinia";
import { formatTableColumn } from "@/views/form/data/table/formatTableColumn";
import { MessageBoxUtil, MessageUtil } from "@/utils/messageUtil";
import { i18n } from "@/i18n";
import { createFormResultRequest, listFormDataTableRequest, updateFormDataDeletedRequest } from "@/api/project/data";
import commonFunction from "@/utils/commonFunction";
import { useUserForm } from "@/views/formgen/components/GenerateForm/hooks/useUserForm";
import { USER_FORM_STATE_KEY } from "@/views/formgen/components/GenerateForm/types/constants";

export const formDataTableProps = {
  mode: {
    type: Number,
    required: false,
    default: 1
  },
  // 权限信息
  authGroup: {
    type: Object,
    required: false,
    default: () => {}
  }
};

export function useFormDataTable(props: any, initGridConfig = {}) {
  const formKey = ref<string>("");
  const formConfig = ref({
    formKey: "",
    preview: false,
    showBtns: true
  });
  const formParseKey = ref(new Date().getTime());
  const formModel = ref<Record<string, any>>({});
  const queryParams = ref<any>({
    authGroupId: null,
    formKey: "",
    filter: {}
  });

  const queryDialogVisible = ref(false);

  const addDialogVisible = ref(false);
  const selectDataId = ref(null);
  const checkboxIds = ref([]);
  const fields = ref<FieldItem[]>([]);
  const fixedFields = ref([]);

  const inputSearch = ref("");

  const initPerms = () => {
    if (props.mode === 1) {
      const btns = ["print", "custom"];
      btns.forEach(key => {
        gridOptions.value.toolbarConfig[key] = true;
      });
      return true;
    }
    props.authGroup.btnPerms.forEach((key: string) => {
      if (key !== "export") {
        gridOptions.value.toolbarConfig[key] = true;
      }
    });
    fields.value.forEach(field => {
      let haveFieldIds = props.authGroup.fieldEditPerms;
      if (!haveFieldIds.includes(field.value)) {
        if (field.scheme) {
          field.scheme.disabled = true;
        }
      }
    });
  };

  const route = useRoute();
  const router = useRouter();
  const formLogicData = ref(null);

  const dimensionConfig = ref<any>();

  onBeforeMount(async () => {
    formKey.value = (route.query.key as string) || (route.params.key as string);
    // 详情固定列
    listFixedFormFieldsRequest(formKey.value).then(res => {
      fixedFields.value = res.data;
    });
    // 表格字段查询
    handleQueryFields().then(() => {
      initPerms();
    });
    // 获取逻辑
    const { data: logicData } = await getFormLogicRequest({ formKey: formKey.value });
    formLogicData.value = logicData;
    // 获取维度信息
    if (formType.value === 4) {
      getDimensionByKey(formKey.value).then(res => {
        if (res.data) {
          dimensionConfig.value = res.data;
        }
      });
    }
  });
  const formInfoStore = useFormInfo();

  const { myFormRole, formType } = storeToRefs(formInfoStore);

  const checkBtnPerms = (btn: string) => {
    if (props.mode === 2) {
      return props.authGroup.btnPerms.includes(btn);
    } else if (myFormRole.value === MyFormRole.COLLABORATOR) {
      return formInfoStore.authGroupInfo?.btnPerms.includes(btn);
    } else {
      return true;
    }
  };

  const handleConditionQueryTable = () => {
    queryDialogVisible.value = false;
    handleReloadTable();
  };

  const handleQueryFields = () => {
    return new Promise((resolve, reject) => {
      // 普通模式
      if (props.mode === 2 || myFormRole.value === MyFormRole.COLLABORATOR) {
        // 是不是协作者身份
        let tempAuthGroup = props.authGroup;
        if (myFormRole.value === MyFormRole.COLLABORATOR) {
          tempAuthGroup = formInfoStore.authGroupInfo || {};
        }
        listFormFieldsRequest(formKey.value).then(res => {
          let haveFieldIds = tempAuthGroup.fieldVisiblePerms;
          fields.value = res.data.filter(item => haveFieldIds.includes(item.value));
          handleTableColumns(fields.value);
          resolve(fields.value);
        });
        queryParams.value.authGroupId = tempAuthGroup.id;
      } else {
        listFormFieldsRequest(formKey.value)
          .then(res => {
            handleTableColumns(res.data);
            resolve(fields.value);
          })
          .catch(() => {
            reject();
          });
      }
    });
  };

  const handleTableColumns = (data: any) => {
    let firstCol = [
      { type: "checkbox", width: 60, title: "" },
      {
        field: "id",
        title: "Id",
        minWidth: "150"
      }
    ];
    gridOptions.value.columns = firstCol.concat(
      data
        .map((item: any) => {
          return formatTableColumn(item);
        })
        .filter((item: any) => item !== undefined)
    );
    fields.value = data;
  };

  const handleQuery = () => {
    queryDialogVisible.value = true;
  };

  const dataImportRef = ref<any>(null);

  const handleImport = () => {
    dataImportRef.value!.upload.open = true;
  };

  const baseTableRef = ref<any>(null);
  const dataExportRef = ref<any>(null);

  const selectRecords = ref([]);

  const handleExport = () => {
    const { pager } = baseTableRef.value!.getXGrid().getProxyInfo();
    let params = {
      selectRecords: selectRecords.value,
      currentPage: pager.currentPage - 1,
      pageSize: pager.pageSize,
      total: pager.total,
      formKey: formKey.value,
      filter: queryParams.value.filter,
      authGroupId: queryParams.value.authGroupId,
      checkboxIds: baseTableRef
        .value!.getXGrid()
        .getCheckboxRecords()
        .map((item: any) => item.id)
    };
    dataExportRef.value!.openExportDialog(params);
  };

  const downloadFileRef = ref<any>(null);

  const handleDownload = () => {
    if (!baseTableRef.value!.getXGrid().getProxyInfo().pager.total) {
      MessageUtil.error(i18n.global.t("form.formData.formNoFileCollected"));
      return;
    }
    downloadFileRef.value!.openDownloadFile(
      baseTableRef
        .value!.getXGrid()
        .getCheckboxRecords(true)
        .map((item: any) => item.id)
    );
  };

  const handleExamAssignScore = () => {
    router.push({
      path: "/exam/score/assign",
      query: {
        formKey: formKey.value
      }
    });
  };

  const dataRecycleRef = ref<any>(null);

  const handleOpenDataRecycle = () => {
    dataRecycleRef.value!.open();
  };

  const printTemplateListRef = ref<any>(null);

  const handleBatchPrint = () => {
    let ids = baseTableRef
      .value!.getXGrid()
      .getCheckboxRecords(true)
      .map((item: any) => item.id);
    if (!ids.length) {
      MessageUtil.warning(i18n.global.t("form.formData.selectData"));
      return;
    }
    checkboxIds.value = ids;
    printTemplateListRef.value!.showClick();
  };

  const handleDelete = () => {
    let ids = baseTableRef
      .value!.getXGrid()
      .getCheckboxRecords(true)
      .map((item: any) => item.id);
    if (!ids.length) {
      MessageUtil.warning(i18n.global.t("form.formData.selectData"));
      return;
    }
    MessageBoxUtil.confirm(
      `${i18n.global.t("form.formData.deleteConfirmation")}${ids.length}${i18n.global.t(
        "form.formData.deleteConfirmationCount"
      )}`,
      () => {
        updateFormDataDeletedRequest(formKey.value, ids, true).then(() => {
          MessageUtil.success(i18n.global.t("formI18n.all.success"));
          handleReloadTable();
        });
      }
    );
  };

  const handleAdd = () => {
    formConfig.value.formKey = formKey.value;
    formParseKey.value = new Date().getTime();
    addDialogVisible.value = true;
  };

  const handleReloadTable = () => {
    baseTableRef.value!.getXGrid().commitProxy("query");
  };

  const { height } = useWindowSize();

  const gridOptions = ref<any>({
    minHeight: 500,
    maxHeight: height.value - 90,
    border: true,
    stripe: true,
    resizable: true,
    showHeaderOverflow: true,
    showOverflow: true,
    highlightHoverRow: true,
    keepSource: true,
    id: "formDataGrid",
    rowConfig: {
      keyField: "id",
      isHover: true
    },
    customConfig: {
      storage: true
    },
    printConfig: {},
    menuConfig: {
      body: {
        options: [
          [
            {
              code: "copy",
              name: i18n.global.t("form.formData.copyContent"),
              visible: true,
              disabled: false
            },
            {
              code: "clear",
              name: i18n.global.t("form.formData.clearContent"),
              visible: true,
              disabled: false
            }
          ]
        ]
      }
    },
    sortConfig: {
      trigger: "cell",
      remote: true
    },
    filterConfig: {
      remote: true
    },
    pagerConfig: {
      pageSize: 10,
      pageSizes: [5, 10, 15, 20, 50, 100, 200, 500, 1000]
    },
    toolbarConfig: {
      refresh: true,
      import: false,
      print: false,
      zoom: true,
      custom: false,
      slots: {
        buttons: "toolbar_buttons",
        tools: "toolbar_tools"
      }
    },
    proxyConfig: {
      seq: true, // 启用动态序号代理，每一页的序号会根据当前页数变化
      sort: true, // 启用排序代理，当点击排序时会自动触发 query 行为
      filter: true, // 启用筛选代理，当点击筛选时会自动触发 query 行为
      // 对应响应结果 { result: [], page: { total: 100 } }
      props: {
        result: "data.rows", // 配置响应结果列表字段
        total: "data.total" // 配置响应结果总页数字段
      },
      ajax: {
        // 接收 Promise 对象
        //@ts-ignore
        query: ({ page }) => {
          queryParams.value.size = page.pageSize;
          queryParams.value.current = page.currentPage - 1;
          queryParams.value.formKey = formKey.value;
          // A workaround for handle empty filter condition
          const filter = queryParams.value.filter;
          if (filter && filter?.conditionList) {
            //@ts-ignore
            filter.conditionList = filter.conditionList.filter(({ formItemId, method, value }) => {
              return formItemId !== "" && method !== "" && (value !== "" || method === "IS_NULL" || method === "NOT_NULL");
            });
          }
          return listFormDataTableRequest(queryParams.value);
        }
      }
    },
    columns: [],
    importConfig: {
      // remote: true,
      // importMethod: this.importMethod,
      types: ["csv", "html", "xml", "txt"],
      modes: ["insert"]
    },
    checkboxConfig: {
      // labelField: 'id',
      reserve: true,
      highlight: true,
      range: true
    },
    ...initGridConfig
  });

  //@ts-ignore
  const cellContextMenuEvent = ({ row }) => {
    const $grid = baseTableRef.value!.getXGrid();
    $grid.setCurrentRow(row);
  };

  const viewOrUpdateDialogRef = ref<any>(null);

  const handleViewOrUpdate = (event: any) => {
    if (!checkBtnPerms("detail")) {
      return;
    }
    if (event.triggerCheckbox) {
      return;
    }
    formModel.value = event.row;
    selectDataId.value = event.row.id;
    console.log(baseTableRef.value);
    viewOrUpdateDialogRef.value!.showDialog(event.row, baseTableRef.value!.getXGrid().getTableData()?.fullData || []);
  };

  const { copyText } = commonFunction();

  //@ts-ignore
  const contextMenuClickEvent = ({ menu, row, column }) => {
    const $grid = baseTableRef.value!.getXGrid();
    switch (menu.code) {
      case "copy":
        if (row && column) {
          copyText(row[column.property]);
        }
        break;
      case "clear":
        $grid.clearData(row, column.property);
        break;
      case "myPrint":
        $grid.print();
        break;
      case "myExport":
        $grid.exportData();
        break;
    }
  };

  const userFormStore = useUserForm();
  const { submitLoading } = userFormStore;
  provide(USER_FORM_STATE_KEY, userFormStore);

  const submitForm = async (data: any) => {
    try {
      await createFormResultRequest({
        ...data,
        formKey: formConfig.value.formKey
      });
      handleReloadTable();
      addDialogVisible.value = false;
      MessageUtil.success(i18n.global.t("formI18n.all.success"));
    } catch (e) {
      console.error(e);
    } finally {
      submitLoading.value = false;
    }
  };

  const handleInputSearchChange = () => {
    queryParams.value.filter["keyword"] = inputSearch.value;
    handleReloadTable();
  };

  const handleCheckboxChange = () => {
    checkboxIds.value = baseTableRef
      .value!.getXGrid()
      .getCheckboxRecords(true)
      .map((item: any) => item.id);
  };

  const handleCheckboxAll = () => {
    checkboxIds.value = baseTableRef
      .value!.getXGrid()
      .getCheckboxRecords(true)
      .map((item: any) => item.id);
  };

  // 批量编辑相关
  const batchEditRef = ref();

  // 批量编辑方法
  const handleBatchEdit = () => {
    batchEditRef.value.show();
  };

  return {
    formKey,
    formConfig,
    formParseKey,
    formModel,
    queryParams,
    queryDialogVisible,
    addDialogVisible,
    selectDataId,
    checkboxIds,
    fields,
    fixedFields,
    inputSearch,
    initPerms,
    handleConditionQueryTable,
    handleQueryFields,
    handleTableColumns,
    handleQuery,
    dataImportRef,
    handleImport,
    baseTableRef,
    dataExportRef,
    selectRecords,
    handleExport,
    downloadFileRef,
    handleDownload,
    handleExamAssignScore,
    dataRecycleRef,
    handleOpenDataRecycle,
    printTemplateListRef,
    handleBatchPrint,
    handleDelete,
    handleAdd,
    handleReloadTable,
    gridOptions,
    cellContextMenuEvent,
    viewOrUpdateDialogRef,
    handleViewOrUpdate,
    contextMenuClickEvent,
    userFormStore,
    submitForm,
    handleInputSearchChange,
    checkBtnPerms,
    formLogicData,
    dimensionConfig,
    formType,
    handleCheckboxChange,
    handleCheckboxAll,
    batchEditRef,
    handleBatchEdit
  };
}
